/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.Arsanesia.TempleRush.Models;


import java.util.Random;

import com.Arsanesia.TempleRush.Controllers.World;
import com.Arsanesia.TempleRush.Enumeration.GeenieEnumeration;
import com.Arsanesia.TempleRush.Enumeration.GeenieStateEnumeration;
import com.Arsanesia.TempleRush.Enumeration.Notif;
import com.Arsanesia.TempleRush.Views.Screens.AbstractScreen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Array;


/**
 *
 * @author Chairul Ichsan
 */
public class GeenieManager implements Updateable{

    public static final int MAX_GEENIE_COUNT = 5;

    public final float LINE_HEIGHT[];
    private int geenieCount;
    private int touchedGeenieIndex;
    private int createTry;
    private Geenie geenies[];
    private Array<Array<Sprite>> geenieSprites;
    private Array<Sprite> destroyedGeenieSprites;
    private float geenieHeight, geenieWidth;
    private int maxGeenieColor;
    private boolean newGeenieAdded;

    public GeenieManager(TextureAtlas atlas, World world) {
        geenieCount = 0;
        createTry = 0;
        //detect new geenie
        maxGeenieColor = -1;
        
        geenies = new Geenie[MAX_GEENIE_COUNT];
        //create array of array of sprites for geenie sprites
        Gdx.app.log(this.getClass().getName(), GeenieEnumeration.values().length + ": enumeration length");
        geenieSprites = new Array<Array<Sprite>>(GeenieEnumeration.values().length);
        
        
        //cache all type of geenies sprites
        for(int i=0;i<GeenieEnumeration.values().length;i++)
        {	
        	Gdx.app.log("enum value geenie: ", GeenieEnumeration.values()[i].name());
        	geenieSprites.add(atlas.createSprites(GeenieEnumeration.values()[i].name()));
        }
        
        //create destroyed geenie sprites
        Gdx.app.log(this.getClass().getName(), "create destroyed sprites");
        destroyedGeenieSprites = atlas.createSprites("DESTROYED");
        geenieHeight = geenieSprites.get(0).get(0).getHeight();
        geenieWidth = geenieSprites.get(0).get(0).getWidth();
        
        for (int i = 0; i < geenies.length; i++) {
        	//construct geenie
            geenies[i] = new Geenie(new TextureRegion(geenieSprites.first().first()), world);
            //set initial live animation
            geenies[i].setLiveAnimation(geenieSprites.first());
            //set all the geenies destroyed animation
            //it's all the same
            geenies[i].setDestroyedAnimation(destroyedGeenieSprites);
        }

        
        LINE_HEIGHT = new float[] {AbstractScreen.VIEWPORT_DEFAULTHEIGHT - geenieHeight, AbstractScreen.VIEWPORT_DEFAULTHEIGHT - geenieHeight*2,AbstractScreen.VIEWPORT_DEFAULTHEIGHT - geenieHeight*3};
    }
    public Geenie[] getGeenies(){
    	return this.geenies;
    }
    
    public TextureRegion debugSprite(){
    	return this.geenies[0].getLiveAnimation().getKeyFrame(0f);
//    	return this.geenieSprites.get(0).get(0);
    }
    public void addGeeniesToStage(Stage stage){
    	for(int i=0;i<geenies.length;i++)
    		stage.addActor(geenies[i].getGeenieImage());
    }
     
    public boolean needSpawn() {
        return geenieCount < MAX_GEENIE_COUNT;
    }
    public GeenieEnumeration getNewGeenie(){
    	return GeenieEnumeration.values()[maxGeenieColor];
    }
    
    public void setNewGeenieAdded(boolean tutormode){
    	this.newGeenieAdded = tutormode;
    }
    public void spawnGeenie(int level, int[] availableColor) {
        Random rand = new Random();

        while (geenieCount < World.MAX_JIN_IN_WORLD) {
            /*
             * Find inactive geenie
             */
        	Gdx.app.log("available", GeenieEnumeration.values()[availableColor[0]].name()+","
        							+GeenieEnumeration.values()[availableColor[1]].name()+","
        							+GeenieEnumeration.values()[availableColor[2]].name()+","
        							+GeenieEnumeration.values()[availableColor[3]].name()+",");
            int inactiveGeenieIndex = getInactiveGeenieIndex();
            /*
             * Set Geenie Attributes
             */
            int rng = rand.nextInt(100);
            int color = getNewGeenieColor(level, availableColor);
            Gdx.app.log("geenie","number: "+color);
            GeenieEnumeration geenieColor = GeenieEnumeration.values()[color];
            
            //detect new GeenieColor
            if(maxGeenieColor< geenieColor.ordinal()){
            		maxGeenieColor = geenieColor.ordinal();
            		newGeenieAdded = true;
            }
            
            if(inactiveGeenieIndex >-1)
            {
	            geenies[inactiveGeenieIndex].setAttributes(geenieColor, // Color
	                    rng % 2 == 0 ? Geenie.MOVE_RIGHT : Geenie.MOVE_LEFT, // Direction
	                    getNewGeenieSpeed(level), // Speed
	                    rng % 2 == 0 ? (0 - (geenieWidth + rng)) : (AbstractScreen.VIEWPORT_DEFAULTWIDTH + geenieWidth + rng), // X Pos
	                    LINE_HEIGHT[rand.nextInt(3)]// Y Pos
	                    );     // Image
	            
	            //set the geenie sprite
	            Gdx.app.log("geenie", geenieColor.toString());
	            geenies[inactiveGeenieIndex].setLiveAnimation(geenieSprites.get(geenieColor.ordinal()));
            }
            /*
             * Check fail condition
             */
            boolean failCondition = false;

            for (int i = 0; i < geenies.length; i++) {
                if (geenies[i].isActive()) {
                    if (geenies[i].isOverlaps(geenies[inactiveGeenieIndex].getBound())) {
                        failCondition = true;
                    }
                    if (geenies[i].getY() == geenies[inactiveGeenieIndex].getY()
                            && geenies[i].getDirection() != geenies[inactiveGeenieIndex].getDirection()) {
                        failCondition = true;
                    }
                }
            }

            if (!failCondition) {
                /*
                 * Set Geenie Active
                 */
            	if(inactiveGeenieIndex >-1 && inactiveGeenieIndex<geenies.length) geenies[inactiveGeenieIndex].setActive(true);
                ++geenieCount;
                createTry = 0;
                Gdx.app.log("inactivegeenieindex: ", inactiveGeenieIndex+"");
            } else {
                ++createTry;
            }
            
            if (createTry > 100) {
                resetGeenie();
            }
        }
    }

    public void resetGeenie() {
        for (int i = 0; i < geenies.length; i++) {
            geenies[i].setActive(false);
        }

        geenieCount = 0;
        createTry = 0;
    }

    public Geenie getTouchedGeenie() {
        return geenies[touchedGeenieIndex];
    }

    public int getInactiveGeenieIndex() {
        for (int i = 0; i < geenies.length; i++) {
            if (!geenies[i].isActive()) {
                return i;
            }
        }

        return -1;
    }

    public float getNewGeenieSpeed(int level) {
        return Geenie.DEFAULT_SPEED+(level*0.1f);
    }

    public int getNewGeenieColor(int level, int[] availableColor) {
        
//    	int colorNumber = 1;
//        if (level > 0) {
//            colorNumber++;
//        }
//        if (level > 2) {
//            colorNumber++;
//        }
//        if (level > 3) {
//            colorNumber++;
//        }
//        if (level > 4) {
//            colorNumber++;
//        }

        Random rand = new Random();
        int randomNumber = rand.nextInt(101);

        if (randomNumber < 75 || level < 1) { // 75% muncul jin biasa
            return availableColor[rand.nextInt(4)];
        } else {
            if (level > 6) {
                return (rand.nextInt(4)) + 5;
            } else if(level>3){
            	return (rand.nextInt(level-3)+5);
            }/*if (level > 5) {
                return (rand.nextInt(2)) + 4;
            } else if (level > 4) {
                return (rand.nextInt(1)) + 4;
            } */else if (level > 0) {
                return GeenieEnumeration.WHITE.ordinal();
            }
        }

        return 0;
    }

    public int getTouchedGeenieType(){
    	for (int i = 0; i < geenies.length; i++) {
          int geenieHit = (geenies[i].isDestroyed())? geenies[i].getGeenieType().ordinal():-1;

          if (geenieHit != -1 && geenieHit != GeenieEnumeration.BLACK.ordinal()) {
              touchedGeenieIndex = i;
              return geenieHit;
          }
    	}
    	return -1;
    }

    public void update(World world) {
    	//start the tutorial if tutorial in game configuration is on
    	if(newGeenieAdded&&GameConfiguration.isTutorial()) world.startTutorMode();
        for (int i = 0; i < geenies.length; i++) {
                geenies[i].update();
                
            //out of bound geenie
            if ((geenies[i].getDirection() == Geenie.MOVE_LEFT && geenies[i].getX() < 0 - geenies[i].getWidth())
                    || (geenies[i].getDirection() == Geenie.MOVE_RIGHT && geenies[i].getX() > AbstractScreen.VIEWPORT_DEFAULTWIDTH + geenies[i].getWidth())) {
                geenies[i].setActive(false);
                --geenieCount;
                //if black geenie out of bound than activate it's effect
                if(geenies[i].getGeenieType() == GeenieEnumeration.BLACK){
                	world.getNotif().setType(Notif.MISS);
                	world.getTemple().blackGeenieEffect();
                }
            } else {
                if (geenies[i].getState() == GeenieStateEnumeration.DISAPPEAR) {
                    geenies[i].setActive(false);
                    --geenieCount;
                }
            }
        }
    }
	@Override
	public void update() {
		// TODO Auto-generated method stub
		
	}


}
